package tazadum.engine;

import java.util.Arrays;

public class Signal {
	public static final int CHANNEL_SINE_05s = 0;
	public static final int CHANNEL_SINE_1s = 1;
	public static final int CHANNEL_SINE_5s = 2;

	public static final int CHANNEL_SAW_05s = 5;
	public static final int CHANNEL_SAW_1s = 6;
	public static final int CHANNEL_SAW_2s = 7;
	public static final int CHANNEL_SAW_5s = 8;

	public static final int CHANNEL_ZERO = 10;
	public static final int CHANNEL_1_QUARTER = 11;
	public static final int CHANNEL_HALF = 12;
	public static final int CHANNEL_3_QUARTER = 13;
	public static final int CHANNEL_ONE = 14;

	public static final int CHANNEL_R = 20;
	public static final int CHANNEL_G = 21;
	public static final int CHANNEL_B = 22;

	public static final int CHANNEL_SYNTH_ENV_0 = 32;
	public static final int CHANNEL_SYNTH_ENV_1 = 33;
	public static final int CHANNEL_SYNTH_ENV_2 = 34;
	public static final int CHANNEL_SYNTH_ENV_3 = 35;
	public static final int CHANNEL_SYNTH_ENV_4 = 36;
	public static final int CHANNEL_SYNTH_ENV_5 = 37;
	public static final int CHANNEL_SYNTH_ENV_6 = 38;
	public static final int CHANNEL_SYNTH_ENV_7 = 39;
	public static final int CHANNEL_SYNTH_ENV_8 = 40;

	private static final int MAX_CHANNELS = 1023;
	private final float[] write;
	private final float[] read;

	public Signal() {
		write = new float[MAX_CHANNELS];
		read = new float[MAX_CHANNELS];
	}

	public void channel(final int id, final float value) {
		if (value > write[id]) {
			write[id] = value;
		}
	}

	public float channel(final int id) {
		return read[id];
	}

	public void generateBuiltInChannels(final float time, float dt) {
		final float time05s = time * 2f;
		final float time2s = time * 0.5f;
		final float time5s = time * 0.2f;

		final float factor = 1 - 0.05f * dt;
		for (int i = 0; i < MAX_CHANNELS; i++) {
			// System.arraycopy(write, 0, read, 0, MAX_CHANNELS);
			read[i] = write[i];
			write[i] *= factor;
		}
		Arrays.fill(write, 0);

		write[CHANNEL_SAW_05s] = time05s - (int) time05s;
		write[CHANNEL_SINE_05s] = (float) (Math.sin(time05s * 3.1415 * 2) * 0.5 + 0.5);
		write[CHANNEL_SAW_1s] = time - (int) time;
		write[CHANNEL_SINE_1s] = (float) (Math.sin(time * 3.1415 * 2) * 0.5 + 0.5);
		write[CHANNEL_SAW_2s] = time2s - (int) time2s;
		write[CHANNEL_SAW_5s] = time5s - (int) time5s;
		write[CHANNEL_SINE_5s] = (float) (Math.sin(time5s * 3.1415 * 2) * 0.5 + 0.5);

		write[CHANNEL_ZERO] = 0.00f;
		write[CHANNEL_1_QUARTER] = 0.25f;
		write[CHANNEL_HALF] = 0.50f;
		write[CHANNEL_3_QUARTER] = 0.75f;
		write[CHANNEL_ONE] = 1.00f;

		write[CHANNEL_R] = 1;
		write[CHANNEL_G] = 1;
		write[CHANNEL_B] = 1;
	}
}
